package com.dw.test;

import org.apache.commons.codec.binary.Hex;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

public class MD5SHA_Main {
    public static void main(String[] args) throws Exception {
//        System.out.println(String.format("combine:auth:login:refuse:%s:%s"  , "daiwei", DateUtil.formatDateTime(new Date())));
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date nextTimePoint = new Date();
//        Date now_10 = new Date(nextTimePoint.getTime() - 300000);
//        Date now_a_10 = new Date(nextTimePoint.getTime() + 300000);
//        System.out.println(sdf.format(nextTimePoint));
//        System.out.println(sdf.format(now_10));
//        System.out.println(sdf.format(now_a_10));
//        System.out.println(now_10.after(now_a_10));
//System.out.println(encryMD5("123456"));
        //MD5+salt
//        System.out.println(TestMain.encryMD5Salt("123456"));
//        System.out.println(verify("123456",TestMain.encryMD5Salt("123456")));
        //SHA-1
//        System.out.println(encryptSHA("Hello, this is a SHA-256 hash demo!".getBytes()));
//        System.out.println(SHAEncrypt("Hello, this is a SHA-256 hash demo!"));
//        System.out.println(SHA256Encrypt("Hello, this is a SHA-256 hash demo!"));
//
//        //SHA-2
//        // 定义待哈希的明文字符串
//        String data = "Hello, this is a SHA-256 hash demo!";
//        // 计算 SHA-256 哈希值
//        String hash = sha256(data);
//
//        // 输出原始数据和对应的哈希值
//        System.out.println("原始数据: " + data);
//        System.out.println("SHA-256 哈希值: " + hash);

        //base64
//        byte[] bytes  = "123456".getBytes();
//        System.out.println("Base64加密前："+ Arrays.toString(bytes));
//        byte[] encodeBytes = Base64.encodeBase64(bytes);
//        System.out.println("Base64加密后："+Arrays.toString(encodeBytes));
//        System.out.println("Base64解密后："+Arrays.toString(Base64.decodeBase64(encodeBytes)));
//        System.out.println(new String(bytes, StandardCharsets.UTF_8));
    }
    public static String encryMD5Salt(String data) throws Exception {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        //每次的盐都是随机的
        String salt = UUID.randomUUID().toString().substring(0,16);
        md5.update((data + salt).getBytes());
        //获取十六进制字符串形式的MD5摘要
        String password = new String(new Hex().encode(md5.digest()));
        char[] cs = new char[48];
        for (int i = 0; i < 48; i += 3) {
            cs[i] = password.charAt(i / 3 * 2);
            char c = salt.charAt(i / 3);
            cs[i + 1] = c;
            cs[i + 2] = password.charAt(i / 3 * 2 + 1);
        }
        return new String(cs);
    }

    /**
     * 校验密码是否正确
     */
    public static boolean verify(String password, String md5) throws NoSuchAlgorithmException {
        char[] cs1 = new char[32];
        char[] cs2 = new char[16];
        for (int i = 0; i < 48; i += 3) {
            cs1[i / 3 * 2] = md5.charAt(i);
            cs1[i / 3 * 2 + 1] = md5.charAt(i + 2);
            cs2[i / 3] = md5.charAt(i + 1);
        }
        String salt = new String(cs2);
        MessageDigest md5Verify = MessageDigest.getInstance("MD5");
        md5Verify.update((password + salt).getBytes());
        return  new String(new Hex().encode(md5Verify.digest())).equals(new String(cs1));
    }

    public static byte[] encryptSHA(byte[] data) throws Exception{
        MessageDigest sha = MessageDigest.getInstance("SHA");
        sha.update(data);
        return sha.digest();
    }


    public static String SHAEncrypt(final String content) {
        try {
            MessageDigest sha = MessageDigest.getInstance("SHA");
            byte[] sha_byte = sha.digest(content.getBytes());
            StringBuffer hexValue = new StringBuffer();
            for (byte b : sha_byte) {
                //将其中的每个字节转成十六进制字符串：byte类型的数据最高位是符号位，通过和0xff进行与操作，转换为int类型的正整数。
                String toHexString = Integer.toHexString(b & 0xff);
                hexValue.append(toHexString.length() == 1 ? "0" + toHexString : toHexString);
            }
            return hexValue.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    //SHA-256加密
    public static String SHA256Encrypt(String sourceStr) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        if (null != md) {
            md.update(sourceStr.getBytes());
            String digestStr = getDigestStr(md.digest());
            return digestStr;
        }

        return null;
    }

    private static String getDigestStr(byte[] digest) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : digest) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    /**
     * SHAHashDemo 类演示了如何使用 Java 的 MessageDigest 类来计算 SHA-256 哈希值。
     * 需要注意的是，SHA 算法是一种单向哈希函数，因此不存在解密操作，
     * 本示例仅展示如何将字符串转换为固定长度的哈希值。
     */

        /**
         * 将输入字符串使用 SHA-256 算法进行哈希，并返回十六进制表示的哈希值。
         *
         * @param input 待哈希的输入字符串
         * @return 十六进制字符串形式的 SHA-256 哈希值
         */
        public static String sha256(String input) {
            try {
                // 获取 SHA-256 算法的 MessageDigest 实例
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
                // 将输入字符串转换为字节数组并计算哈希值
                byte[] hashBytes = digest.digest(input.getBytes("UTF-8"));

                // 将字节数组转换为十六进制字符串
                StringBuilder hexString = new StringBuilder();
                for (byte b : hashBytes) {
                    // 将字节转换为无符号整数，并转换为十六进制字符串
                    String hex = Integer.toHexString(0xff & b);
                    // 如果十六进制字符串长度为 1，前面补 0
                    if (hex.length() == 1) {
                        hexString.append('0');
                    }
                    hexString.append(hex);
                }
                return hexString.toString();
            } catch (Exception e) {
                // 捕获异常并打印堆栈信息
                e.printStackTrace();
                return null;
            }
        }
}
